#include <jni.h>
#include <string>
#include "study/main.h"
#include <android/log.h>
//日志打印
#define TAG "FORREST"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__);


extern "C" JNIEXPORT jstring JNICALL
Java_com_xia_ndk08_1as_1code_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    main();
    return env->NewStringUTF(hello.c_str());
}
extern "C" //支持C语言
JNIEXPORT //Linux 和windows 的jni.h内部定义不一样，这个宏代表暴露出去的标准形式
//windows 对外暴露的标准规定 所有的函数必须是windows系统规则规定的

void JNICALL  //JNICALL这个宏windows和Linux定义也不一样，代表当前函数压栈的规则（形参规则）
//windows中代表函数压栈是从右到左，Linux是从左到右

Java_com_xia_ndk08_1as_1code_MainActivity_test01(JNIEnv *env, jobject thiz) {
    // TODO: implement test01()
    LOGD("TEST01");
}extern "C"
JNIEXPORT void JNICALL
/**
 *
 * @param env Java虚拟机自动携带，为了可以使用JNI的API
 * @param thiz  代表哪个对象使用的 （MainActivity使用）
 * @param number
 * @param text
 * @param int_array
 * @param string_array
 */
Java_com_xia_ndk08_1as_1code_MainActivity_addTest01(JNIEnv *env, jobject thiz, jint number,
                                                    jstring text, jintArray int_array,
                                                    jobjectArray string_array) {
    int m_number = number;
    LOGD("m_nuber=%d", m_number);
    // 参数二：第一层意思，是否在内部完成copy操作，第二层意思，给他一个值，让内部可以运转起来，值随意
    const char *m_text = env->GetStringUTFChars(text, NULL);
    LOGD("m_text=%s", m_text);
    //回收
    env->ReleaseStringUTFChars(text, m_text);
    //打印int数组
    //获取数组
    jint *m_int_array = env->GetIntArrayElements(int_array, NULL);
    //获取数组长度
    jsize int_size = env->GetArrayLength(int_array);
    for (int i = 0; i < int_size; ++i) {
        jint result = *(m_int_array + i);
        //这个会改变java的值
        *(m_int_array + i) += 1000;
        LOGD("m_int_array的值:%d", result);
    }
    // 0代表要刷新,不写java 里的就不会刷新
    env->ReleaseIntArrayElements(int_array, m_int_array, 0);
    //打印string数组
    jsize string_size = env->GetArrayLength(string_array);
    for (int i = 0; i < string_size; ++i) {
        jobject obj = env->GetObjectArrayElement(string_array, i);
        jstring stringResult = static_cast<jstring >(obj);
        const char *result = env->GetStringUTFChars(stringResult, NULL);
        LOGD("string_array的值:%s", result);
        env->ReleaseStringUTFChars(stringResult, result);
    }

}extern "C"
JNIEXPORT void JNICALL
Java_com_xia_ndk08_1as_1code_MainActivity_putStudent(JNIEnv *env, jobject thiz, jobject student) {
    //1.获取字节码文件 ,复制类的包名+类名，把.改为/  ,基本是java 的反射思想
    const char *student_class_str = "com/xia/ndk08_as_code/Student";
    jclass student_class = env->FindClass(student_class_str);
    //2.获取方法 参数1：jclass 参数2：方法名称  参数3：方法签名
    //获取签名：可以在 app/build/intermediates/javac/debug/classes 中使用javap -s com.xia.ndk08_as_code.Student获取
    const char *sign = "(Ljava/lang/String;)V";
    jmethodID setName = env->GetMethodID(student_class, "setName", sign);
    //基本数据类型的签名
    const char *sing2 = "(I)V";
    jmethodID setAge = env->GetMethodID(student_class, "setAge", sing2);
    //静态方法的签名
    const char *sing3 = "()V";
    jmethodID myStaticMethod = env->GetStaticMethodID(student_class, "myStaticMethod", sing3);
    //3.调用对象
    const char *str = "AAAA";
    //参数3 是方法的参数
    jstring str2 = env->NewStringUTF(str);
    env->CallVoidMethod(student, setName, str2);
    env->CallVoidMethod(student, setAge, 888);
    env->CallStaticVoidMethod(student_class, myStaticMethod);

    //回收
    env->DeleteLocalRef(student_class);
    env->DeleteLocalRef(student);

}